#include "FileController.h"

using namespace drogon::nosql;

void FileController::uploadFile(
    const HttpRequestPtr&                         req,
    std::function<void(const HttpResponsePtr&)>&& callback,
    std::string                                   fileName,
    int                                           id,
    std::string                                   token) const
{
    auto redisClientPtr = drogon::app().getFastRedisClient();
    auto userId         = std::to_string(id);
    redisClientPtr->execCommandAsync(
        [req, callback, userId, token](const drogon::nosql::RedisResult& r) {
            Json::Value ret;
            do {
                if (r.type() != RedisResultType::kString) {
                    ret["error"] = "验证信息过期!";
                    break;
                }

                if (r.asString().compare(userId) != 0) {
                    ret["error"] = "非法请求!";
                    break;
                }

                MultiPartParser fileUpload;
                if (fileUpload.parse(req) != 0 ||
                    fileUpload.getFiles().size() != 1) {
                    auto resp = HttpResponse::newHttpResponse();
                    resp->setBody("Must only be one file");
                    resp->setStatusCode(k403Forbidden);
                    callback(resp);
                    return;
                }

                auto& file = fileUpload.getFiles()[0];
                auto  md5  = file.getMd5();
                auto  resp = HttpResponse::newHttpResponse();
                resp->setBody(
                    "The server has calculated the file's MD5 hash to be " +
                    md5);
                file.save();
                LOG_INFO << "The uploaded file has been saved to the ./uploads "
                            "directory";
                callback(resp);
                return;
            } while (false);
            auto resp = HttpResponse::newHttpJsonResponse(ret);
            resp->setStatusCode(k400BadRequest);
            return callback(resp);
        },
        [token, callback](const std::exception& err) {
            LOG_ERROR << "redis error!!! " << err.what();
            auto res = drogon::HttpResponse::newHttpResponse();
            res->setStatusCode(k500InternalServerError);
            return callback(res);
        },
        "GET %s", token.c_str());
}

void FileController::getFile(
    const HttpRequestPtr&                         req,
    std::function<void(const HttpResponsePtr&)>&& callback,
    std::string                                   fileName) const
{
    std::string filePath = drogon::app().getUploadPath();

    auto httpResponsePtr =
        HttpResponse::newFileResponse(filePath.append("/").append(fileName));

    callback(httpResponsePtr);
}